home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
3DDEMO.ZIP
/
3D
/
SOURCE
/
VOXEL.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-16
|
7KB
|
252 lines
#include "voxel.hpp"
// Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
VOXELCLASS::VOXELCLASS(void) // Constructor
{
int count; // setup math tables in 9:23 cos,sin format.
float ang;
double ANG;
ang=0;
for (count=0;count<ANGLE_360;count++)
{
ANG=-ang*DEGREES_TO_RADIANS;
COS[count]=cos(ANG)*65536*128; // put in 23 point format.
SIN[count]=sin(ANG)*65536*128;
ang+=ANGULAR_INCREMENT;
}
Yaw=ANGLE_90; // start facing here
Altitude=(400<<16);
Pitch=DEFAULTPITCH;
Speed=DEFAULTSPEED;
viewpoint_x=128<<23;
viewpoint_y=128<<23;
_SKYHEIGHT = SKYHEIGHT;
}
VOXELCLASS::~VOXELCLASS(void) // Destructor
{
if (_ShadowPAL != NULL)
delete _ShadowPAL;
if (ShadowCenter != NULL)
delete ShadowCenter;
if (ShadowLeft != NULL)
delete ShadowLeft;
if (ShadowRight != NULL)
delete ShadowRight;
if (_Skymap != NULL)
delete _Skymap;
if (_Colormap != NULL)
delete _Colormap;
if (_Heightmap != NULL)
delete _Heightmap;
}
void VOXELCLASS::CreateDataBase(VIDEOCLASS *Video)
{
FILE *fptr;
char buffer[30],texturemap[30];
_ShadowPAL = new unsigned char [ sizeof(char)*256*2 ]; // 2 colors
if (_ShadowPAL==NULL)
Error("Not enough memory\n");
fptr=fopen("data/shadow.pal","rb");
if (fptr==NULL)
Error("Couldn't load Shadow palette\n");
fread((void *)buffer,sizeof(char),27,fptr); // header.
fread((void *)texturemap,sizeof(char),30,fptr);
fread((void *)_ShadowPAL,sizeof(unsigned char),256*2,fptr);
fclose(fptr);
// Load in Shadow maps.
ImageStats *FileStats;
unsigned char *bitmap;
bitmap = Video->LoadPcxFile("images/shmask.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
ShadowCenter = new unsigned char [ sizeof(char)*FileStats->size ];
if (ShadowCenter==NULL)
Error("Not enough memory\n");
memcpy(ShadowCenter,bitmap,FileStats->size);
bitmap = Video->LoadPcxFile("images/shmaskl.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
ShadowLeft = new unsigned char [ sizeof(char)*FileStats->size ];
if (ShadowLeft==NULL)
Error("Not enough memory\n");
memcpy(ShadowLeft,bitmap,FileStats->size);
bitmap = Video->LoadPcxFile("images/shmaskr.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
ShadowRight = new unsigned char [ sizeof(char)*FileStats->size ];
if (ShadowRight==NULL)
Error("Not enough memory\n");
memcpy(ShadowRight,bitmap,FileStats->size);
_ShadowmapPtr=ShadowCenter; // default to center mask.
// Load in Regular maps.
long count;
// LOAD IN CLOUDMAP
bitmap = Video->LoadPcxFile("images/clouds.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
_Skymap = new unsigned char [ sizeof(char)*FileStats->size ];
if (_Skymap==NULL)
Error("Not enough memory\n");
memcpy(_Skymap,bitmap,FileStats->size);
// LOAD IN COLORMAP
bitmap = Video->LoadPcxFile("images/democ.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
_Colormap = new unsigned char [ sizeof(char)*FileStats->size ];
if (_Colormap==NULL)
Error("Not enough memory\n");
memcpy(_Colormap,bitmap,FileStats->size);
Video->SetAllRgbPalette();
// LOAD IN HEIGHTMAP
bitmap = Video->LoadPcxFile("images/demoh.pcx"); // get pointer to pcx file.
FileStats = Video->GetStats(); // get info on file.
_Heightmap = (long *)calloc(1,(sizeof(long)*FileStats->size));
if (_Heightmap==NULL)
Error("Not enough memory\n");
// WATCOM is weired sometimes. I want 1 meg of memory but if I call
// new it doesn't give it to me (NULL). But if I call calloc manually,
// how come I get the memory?
for (count=0;count< (FileStats->size) ;count++)
_Heightmap[count] = bitmap[count]<<16; // multiply by 65536 to get 16:16 fixed
}
void VOXELCLASS::RenderSky()
{
int leftangle,rightangle;
leftangle=(Yaw-ANGLE_30)&ANGLE_MASK;
rightangle=(Yaw+ANGLE_30)&ANGLE_MASK;
_SkyHoriz=Pitch+25;
_vx=viewpoint_x>>7; // put in 16:16 format.
_vy=viewpoint_y>>7;
_LeftCos = COS[leftangle]>>15;
_LeftSin = SIN[leftangle]>>15;
_RightCos = COS[rightangle]>>15;
_RightSin = SIN[rightangle]>>15;
_SkyLimit=_SkyHoriz;
if (_SkyLimit>SCREENHEIGHT)
_SkyLimit=SCREENHEIGHT;
if (_SkyLimit>0) // only call if some sky to see
RenderSkyLine();
}
void VOXELCLASS::RenderView(unsigned char *DoubleBuffer)
{
int angle;
float Resolution;
_Buffer = DoubleBuffer; // make buffer visible to assembly module.
RenderSky();
angle=(Yaw-ANGLE_30)&ANGLE_MASK;
Resolution = (Altitude>>16)*(0.01); // The higher we go --> reduce resolution (see farther).
if (Resolution<1.0) // If too close to ground move by small (unit steps).
Resolution=1.0;
_kVScale = Resolution*KVSCALE; // if you go higher move in greater unit steps.
for ( _col=0; _col<SCREENWIDTH; _col++)
{
_x=viewpoint_x;
_y=viewpoint_y;
_z=Altitude;
_dx=( COS[angle]*Resolution );
_dy=( SIN[angle]*Resolution );
_dz=( Pitch-(SCREENHEIGHT-1) )*_kVScale;
CastRay();
angle=(angle+1)&ANGLE_MASK;
}
}
void VOXELCLASS::CheckCrashed(void)
{
int Height;
Height=_Heightmap[ GetOffset(viewpoint_x,viewpoint_y) ];
if (Altitude>MAXALTITUDE)
Altitude=MAXALTITUDE;
else
if (Altitude<MINALTITUDE)
Altitude=MINALTITUDE;
if (Height>Altitude)
{
Altitude = Height;
Pitch += PITCHSPEED;
}
}
void VOXELCLASS::HandleInput(INPUTCLASS *Input)
{
if (Input->Is_Key(SCAN_LEFT))
{
Yaw=(Yaw-YAWACCEL)&ANGLE_MASK;
_ShadowmapPtr=ShadowLeft;
}
else
if (Input->Is_Key(SCAN_RIGHT))
{
Yaw=(Yaw+YAWACCEL)&ANGLE_MASK;
_ShadowmapPtr=ShadowRight;
}
else
{
_ShadowmapPtr=ShadowCenter;
}
if (Input->Is_Key(SCAN_UP))
Pitch-=PITCHSPEED;
else
if (Input->Is_Key(SCAN_DOWN))
Pitch+=PITCHSPEED;
else
{
if (Pitch<DEFAULTPITCH)
Pitch++;
else
if (Pitch>DEFAULTPITCH)
Pitch--;
}
viewpoint_x+=VIEWSPEED*COS[Yaw];
viewpoint_y+=VIEWSPEED*SIN[Yaw];
Altitude+=(Speed*(Pitch-DEFAULTPITCH));
CheckCrashed();
}